package com.sktlab.bizconfmobile.model.manager;

import java.util.ArrayList;
import java.util.concurrent.ExecutorService;

import org.apache.mina.core.session.IoSession;

import android.app.Activity;

import com.sktlab.bizconfmobile.activity.AppClass;
import com.sktlab.bizconfmobile.interfaces.IConfControl;
import com.sktlab.bizconfmobile.interfaces.ILoadingDialogCallback;
import com.sktlab.bizconfmobile.model.ACCSession;
import com.sktlab.bizconfmobile.model.ACVSession;
import com.sktlab.bizconfmobile.model.BVSession;
import com.sktlab.bizconfmobile.model.ConfControl;
import com.sktlab.bizconfmobile.model.Conference;
import com.sktlab.bizconfmobile.model.LSSession;
import com.sktlab.bizconfmobile.model.Participant;
import com.sktlab.bizconfmobile.model.ServerLinkSession;
import com.sktlab.bizconfmobile.util.LoadingDialogUtil;
import com.sktlab.bizconfmobile.util.Util;


public class ConferenceManager implements IConfControl{
	
	public static final String TAG = "ConferenceManager";
	
	private ServerLinkSession serverLSSession;
	
	private LSSession lsSession;
	private ACCSession accSession;
	private BVSession bvSession;
	private ACVSession acvSession;
	
	private Conference mActiveConference;
	
	public ConferenceManager(Conference conf){

		
		mActiveConference = conf;
		
		serverLSSession = new ServerLinkSession();
		
		lsSession = new LSSession();
		accSession = new ACCSession();
		bvSession = new BVSession();
		acvSession = new ACVSession(conf);
	}
	
	public ServerLinkSession getServerLSSession() {
		return serverLSSession;
	}

	public void setServerLSSession(ServerLinkSession serverLSSession) {
		this.serverLSSession = serverLSSession;
	}
	
	/**
	 * start the conference user clicked, the account must be valid
	 * @return
	 */
	public void startConf(Activity activity, ILoadingDialogCallback callback){
		
		final LoadingDialogUtil dialog 
			= new LoadingDialogUtil(activity, callback);
		
		ExecutorService service = AppClass.getInstance().getService();
		
		service.submit(new Runnable() {
			
			@Override
			public void run() {
				
				dialog.showDialog("connecting to server");
				
				connectToServer();
				
				ConfControl.waitObj();
				
				if(getServerLSSession().isConnected()) {
					
					dialog.finishDialogSuccessDone();
				}else{
				
					dialog.finishDialogWithErrorMsg();
				}				
			}
		});

	}

	/**
	 * add party to current active conference which start by this app
	 * @param party
	 * @param isModerator
	 */
	public void addPartyToConf(Participant party, boolean isModerator){
		
		addPartyToConf(party, isModerator, mActiveConference.getAttr().getConfId());
	}
	
	//add a party to the specified conference
	public void addPartyToConf(Participant party, boolean isModerator, String confId){
		
		accSession.addPartyToConf(serverLSSession.getSession(), party, isModerator, confId);
	}
	
	private void connectToServer() {
		
		serverLSSession.connect();
	}
	
	public void reset(){
		
		Util.BIZ_CONF_DEBUG(TAG, "reset all variable");
		
		lsSession.reset();
		accSession.reset();
		bvSession.reset();
		acvSession.reset();
	}
	
	public void closeSession() {
		
		if (getServerLSSession().isConnected() 
				&& !Util.isEmpty(getServerLSSession().getSession())
				&& !getServerLSSession().getSession().isClosing()){
			
			Util.BIZ_CONF_DEBUG(TAG, "closing session now");

			//disconnect the party in the conference	
			IoSession session = getServerLSSession().getSession();
			
			ArrayList<Participant> parties =  ContactManager.getInstance().getAllSelectedContacts();
			
			Participant currentUser = ContactManager.getInstance().getCurrentUserObject();
			
			if (!Util.isEmpty(currentUser.getIdInConference())) {
				
				parties.add(currentUser);
			}
			
			for(Participant party: parties) {
				
				String idInfConf = party.getIdInConference();
				
				if(Util.isEmpty(idInfConf)) {
					
					continue;
				}
				
				getAccSession().disconnectParty(session, party);
			}
			
			getAccSession().destoryConf(session, mActiveConference);
			
			if (!ServerLinkSession.isUseTestAddress){

				//close bv session
				getBvSession().close(session, getLsSession());
				getLsSession().close(session);			
			}
		}
		
		serverLSSession.close();
		//reset sequence number and session id
		reset();
	}
	
	public Conference getActiveConference() {
		return mActiveConference;
	}
	
	public void setActiveConference(Conference mActiveConference) {
		this.mActiveConference = mActiveConference;
	}
	
	public LSSession getLsSession() {
		return lsSession;
	}

	public void setLsSession(LSSession lsSession) {
		this.lsSession = lsSession;
	}

	public ACCSession getAccSession() {
		return accSession;
	}

	public void setAccSession(ACCSession accSession) {
		this.accSession = accSession;
	}

	public BVSession getBvSession() {
		return bvSession;
	}

	public void setBvSession(BVSession bvSession) {
		this.bvSession = bvSession;
	}

	public ACVSession getAcvSession() {
		return acvSession;
	}

	public void setAcvSession(ACVSession acvSession) {
		this.acvSession = acvSession;
	}

	@Override
	public void hfControl() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void selfMute() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void allMute(int muteState, int muteParticipant) {
		
		getAccSession().confMute(getServerLSSession().getSession(), muteState, muteParticipant);
	}

	@Override
	public void rollCall() {
		
		getAccSession().rollCall(getServerLSSession().getSession());
	}

	@Override
	public void record(int state) {
		
		getAccSession().record(getServerLSSession().getSession(), state);
	}

	@Override
	public void lockConf(int state) {

		getAccSession().lock(getServerLSSession().getSession(), 
							getActiveConference(), 
							state);
	}

	@Override
	public void otherFunc() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void muteParty(Participant party,  int playMessage) {
	
		getAccSession().muteParty(getServerLSSession().getSession(), party, playMessage);
		
	}			
}
